package com.anxin.registerManagement.config.realm;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.anxin.registerManagement.bean.persist.User;
import com.anxin.registerManagement.mapper.UserMapper;
import com.anxin.registerManagement.util.Const;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * @author 叶前呈
 * @date 2022/1/23 15:02
 * 因为这里只做认证，不做授权，授权为jwt，因此只需要继承AuthenticatingRealm
 */
public class UserNamePassWordRealm extends AuthenticatingRealm {
    private static Logger logger = LoggerFactory.getLogger(UserNamePassWordRealm.class);

    @Autowired
    UserMapper userMapper;

    // TODO 这里需要对前端的密码进行rsa解密，然后通过相同加密方式与数据库密码进行匹配
//    /**
//     * 自定义匹配密码的方法
//     */
//    public UserNamePassWordRealm() {
//        this.setCredentialsMatcher(new CredentialsMatcher() {
//            @Override
//            public boolean doCredentialsMatch(AuthenticationToken authenticationToken, AuthenticationInfo authenticationInfo) {
//                return BCrypt.checkpw(authenticationToken.getCredentials().toString(), authenticationInfo.getCredentials().toString());
//            }
//        });
//    }

    /**
     * 判断token是哪种token，如果token是UserNameToken，则放行
     *
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    /**
     * 认证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 获取前端传来的用户信息
        String userName = authenticationToken.getPrincipal().toString();
        String passWord = authenticationToken.getCredentials().toString();

        // TODO 下面的逻辑是，首先通过用户名查数据库，如果存在，则放行，如果不存在，则返回null
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("pass_word").eq("user_name", userName);
        User user = userMapper.selectOne(queryWrapper);
        if (ObjectUtil.isEmpty(user)) {
            throw new UnknownAccountException();
        }
        logger.info("数据库密码：{}", user.getPassWord());

        // TODO 将数据库密码传给shiro来进行校验
        return new SimpleAuthenticationInfo(userName, user.getPassWord(), getName());
    }
}
